package com.pactera.asmp.server.job.dispatch.impl;

import com.pactera.asmp.server.common.threadpool.workqueue.WorkThreadPoolExecutor;
import com.pactera.asmp.server.common.threadpool.workqueue.WorkThreadRejectedExecutionHandler;
import com.pactera.asmp.server.common.threadpool.workqueue.WrokThreadFactory;
import com.pactera.asmp.server.dao.EventLogMapper;
import com.pactera.asmp.server.entity.EventLog;
import com.pactera.asmp.server.job.dispatch.BaseDispatchBus;
import com.pactera.asmp.server.job.dispatch.DeviceEventListener;
import com.pactera.asmp.server.job.dispatch.EventListener;
import com.pactera.asmp.server.job.dispatch.IBaseEvent;
import com.pactera.asmp.server.job.dispatch.impl.feedback.FeedbackManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.Iterator;
import java.util.Vector;
import java.util.concurrent.*;

@Slf4j
//@Component
public class AsmpTaskDispatchBus extends BaseDispatchBus {



    private static AsmpTaskDispatchBus bus = new AsmpTaskDispatchBus();

    private Vector<EventListener> managers = new  Vector<EventListener>();

    private static ThreadPoolExecutor threadPoolExecutor;

    protected  static int mCorePoolSize = 5;
    protected  static int mMaximumPoolSize = 6;
    protected  static int mKeepAlivewTime = 10 * 1000;
    protected  static TimeUnit mTimeUnit = TimeUnit.MILLISECONDS;
    protected  static BlockingQueue<Runnable> mWorkQueue = new ArrayBlockingQueue<>(20);
    protected  static WrokThreadFactory mWrokThreadFactory = new WrokThreadFactory();
    protected  static WorkThreadRejectedExecutionHandler mWorkThreadRejectedExecutionHandler = new WorkThreadRejectedExecutionHandler();

    private static ExecutorService pool = Executors.newFixedThreadPool(20);

    private AsmpTaskDispatchBus(){
       // threadPoolExecutor = new ThreadPoolExecutor(mCorePoolSize, mMaximumPoolSize, mKeepAlivewTime, mTimeUnit, mWorkQueue, mWrokThreadFactory, mWorkThreadRejectedExecutionHandler);
    }

    public static BaseDispatchBus getDispatchBus(){
        return bus;
    }

    public static AsmpTaskDispatchBus getAsmpDispatchBus(){
        return bus;
    }

    @Override
    public void dispatchEvent(final IBaseEvent event) {
//        WorkThreadPoolExecutor instance = WorkThreadPoolExecutor.getInstance();
        for(EventListener listener : managers){
            pool.execute(new Runnable() {
                @Override
                public void run() {
                        listener.handler(event);
                }
            });
        }
    }

    public  void deviceOnlineEvent(String deviceid){
        for(EventListener listener : managers){
            if(listener instanceof FeedbackManager){
                FeedbackManager fm = (FeedbackManager) listener;
                fm.feedbackForDeviceOnlineById(deviceid);
            }
        }
    }

   @Override
   public boolean onBus(DeviceEventListener listener) {
        managers.add(listener);
        return false;
    }

  @Override
  public  boolean offBus(DeviceEventListener listener) {
        Iterator<EventListener> iterator = managers.iterator();
        while (iterator.hasNext()){
            EventListener next = iterator.next();
            if(next.equals(listener)){
                iterator.remove();
                break;
            }
        }
        return false;
    }


}
